#pragma once
#include "cmsis_os.h"

#include "sal_dwt.h"
#include "log.h"

#include <cstdint>
#include <functional>
#include <string>
#include <vector>
#include <algorithm>
#include <memory>

/**
 * @brief 任务管理类,初始化时在app层创建一个实例,通过该实例创建任务?
 *
 * @todo 确定带捕获列表的λ是否可以转化为没有参数列表的函数指针,不可以则需要重构为宏
 * @todo 确定是否将该模块构建为类,或者直接使用函数封装
 * @todo 以更优雅的方式将任务执行时间记录到task_info_t中,并返回给任务创建者(双重指针?)
 * @todo 任务执行时间记录备选(maybe better)：vTaskGetRunTimeStats(),需要配置打开
 */
template <typename TF, typename IF>
class TaskManager
{
public:
    struct task_dbg_info
    {
        float ex_dt = 0;
        float ex_dt_mx = 0;
        float ex_time = 0;
        float ex_time_mx = 0;
    };

private:
    std::function<TF> task_func_;
    std::function<IF> init_func_;
    std::shared_ptr<osThreadDef_t> thread_def_;

    _Noreturn void TaskFunc(void const *argument)
    {
        if (init_func_)
            init_func_();
        for (;;)
        {
            task_func_();

            // osDelay();
        }
    }

public:
    osThreadId task_handle;
    task_dbg_info dbg_info;

public:
    TaskManager(){};
};